package com.maimao.auth.controller;

import com.maimao.api.auth.AuthApi;
import com.maimao.auth.model.AuthToken;
import com.maimao.auth.service.AuthService;
import com.maimao.core.constant.AuthKey;
import com.maimao.core.constant.Constants;
import com.maimao.core.enums.RespCode;
import com.maimao.core.model.auth.LoginCodeRequest;
import com.maimao.core.model.resp.Result;
import com.maimao.core.utils.CookieUtil;
import com.maimao.core.model.auth.SysLoginRequest;
import com.maimao.core.utils.IPUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author MaoLin Wang
 * @date 2020/11/30 11:09 上午
 */
@RestController
@RequestMapping("/")
public class AuthController extends BaseController implements AuthApi {

    /**
     * 用户名密码登录（目前仅用于后台登录）
     *
     * @param loginRequest 登录请求
     */
    @PostMapping(AuthKey.SYS_LOGIN_URL)
    @Override
    public Result<Object> upLogin(@RequestBody SysLoginRequest loginRequest, @RequestParam("type") String type) {
        if (loginRequest == null || StringUtils.isAnyEmpty(loginRequest.getUsername(), loginRequest.getPassword())) {
            return Result.fail(RespCode.FAIL, "请输入账号和密码");
        }
        if (StringUtils.isEmpty(type) || !type.equals("sys")) {
            return Result.notValid("登录方式非法");
        }
        AuthToken authToken = authService.sysLogin(loginRequest.getUsername(), loginRequest.getPassword(), managerClientId, managerClientSecret, type);

        this.saveCookie(authToken.getAccess_token(), managerCookieDomain, managerCookieMaxAge,Constants.USER_TOKEN_SYS);

        return Result.okData(RespCode.LOGIN_SUCCESS, authToken.getJwt_token());
    }

    /**
     * 用户名/手机/邮箱 + 密码 + 图形验证码登录 会员三个都允许 企业只允许邮箱登录
     *
     * @param type member: 会员登录 company:企业登录
     */
    @PostMapping(AuthKey.WEB_LOGIN_URL)
    @Override
    public Result<Object> webAuth(@RequestBody LoginCodeRequest loginCodeRequest, @RequestParam(value = "type", defaultValue = "member") String type) {
        if (loginCodeRequest == null || StringUtils.isAnyEmpty(loginCodeRequest.getAccount(), loginCodeRequest.getPassword())) {
            return Result.fail(RespCode.FAIL, "请输入账户和密码");
        }

        AuthToken authToken = authService.webLogin(loginCodeRequest.getAccount(), loginCodeRequest.getPassword(), loginCodeRequest.getCode(),
                IPUtil.getIpStr(getRequest()),
                mallClientId, mallClientSecret, type);


        this.saveCookie(authToken.getAccess_token(), mallCookieDomain, mallCookieMaxAge, Constants.USER_TOKEN_WEB);

        return Result.okData(RespCode.LOGIN_SUCCESS, authToken.getJwt_token());
    }

    /**
     * 手机免密登录 目前只允许会员进行手机登录
     *
     * @param type member: 会员登录
     */
    @PostMapping(AuthKey.MOBILE_LOGIN_URL)
    @Override
    public Result<Object> mobileAuth(@RequestBody LoginCodeRequest loginCodeRequest, @RequestParam(value = "type", defaultValue = "member") String type) {
        if (loginCodeRequest == null || StringUtils.isAnyEmpty(loginCodeRequest.getAccount(), loginCodeRequest.getCode())) {
            return Result.fail(RespCode.FAIL, "请输入手机号和验证码");
        }
        if (!type.equals("member")) {
            return Result.notValid("该账户不允许手机登录");
        }

        AuthToken authToken = authService.mobileLogin(loginCodeRequest.getAccount(), loginCodeRequest.getCode(),
                mallClientId, mallClientSecret, type);

        this.saveCookie(authToken.getAccess_token(), mallCookieDomain, mallCookieMaxAge,Constants.USER_TOKEN_WEB);

        return Result.okData(RespCode.LOGIN_SUCCESS, authToken.getJwt_token());
    }


    private void saveCookie(String token, String domain, Integer cookieMaxAge,String key) {

        CookieUtil.addCookie(getResponse(), domain, "/",key, token, cookieMaxAge, false);

    }


    @PostMapping("/sys-logout")
    @Override
    public Result sysLogout() {
        String token = getShortToken(getRequest(),Constants.USER_TOKEN_SYS);
        if (token == null) {
            return Result.fail(RespCode.FAIL);
        }
        authService.logout(token, getRequest());
        this.saveCookie(token, managerCookieDomain, 0,Constants.USER_TOKEN_SYS);
        return Result.ok(RespCode.OK, "退出成功");
    }

    @PostMapping("/web-logout")
    @Override
    public Result webLogout() {
        String token = getShortToken(getRequest(),Constants.USER_TOKEN_WEB);
        if (token != null) {
            authService.logout(token, getRequest());
        }
        this.saveCookie(token, mallCookieDomain, 0,Constants.USER_TOKEN_WEB);
        return Result.ok(RespCode.OK, "退出成功");
    }

    @PostMapping("/get-jwt")
    @Override
    public Result<String> getJwt(@RequestBody Map<String, String> data) {
        String cookie = data.get("cookie");
        if (StringUtils.isEmpty(cookie)) {
            return Result.notValid("身份过期");
        }
        String jwt = authService.getJwt(cookie);
        if (StringUtils.isEmpty(jwt)) {
            return Result.notValid("身份过期");
        }
        return Result.okData(jwt);
    }

    /**
     * 取出登录用户的Cookie中的token
     *
     * @param request
     * @return
     */
    private String getShortToken(HttpServletRequest request,String cookieKey) {
        Map<String, String> cookie = CookieUtil.getCookie(request, cookieKey);
        if (cookie != null) {
            return cookie.get(cookieKey);
        }
        return null;
    }

    @Autowired
    private AuthService authService;


    @Value("${auth.manager.clientId}")
    private String managerClientId;

    @Value("${auth.manager.clientSecret}")
    private String managerClientSecret;

    @Value("${auth.manager.cookieDomain}")
    private String managerCookieDomain;

    @Value("${auth.manager.cookieMaxAge}")
    private Integer managerCookieMaxAge;

    @Value("${auth.mall.clientId}")
    private String mallClientId;

    @Value("${auth.mall.clientSecret}")
    private String mallClientSecret;

    @Value("${auth.mall.cookieDomain}")
    private String mallCookieDomain;

    @Value("${auth.mall.cookieMaxAge}")
    private Integer mallCookieMaxAge;
}
